<script lang="ts">
	import { Any } from '$lib/api/proto/google/protobuf/any';
	import type { QuestionInfo } from '$lib/api/proto/resource_exam_api';
	import {
		ChoiceQuestion,
		SimpleQuestion,
		TrueOrFalseQuestion
	} from '$lib/api/proto/resource_exam_type_api';
	import { appStore } from '$lib/stores/app.svelte';
	import { userStore } from '$lib/stores/user.svelte';
	import { callApi } from '$lib/utils/call_utils';
	import EditChoiceQuestion from './EditChoiceQuestion.svelte';
	import EditSimpleQuestion from './EditSimpleQuestion.svelte';
	import EditTrueOrFalseQuestion from './EditTrueOrFalseQuestion.svelte';

	interface Props {
		resourceId: string;
		question?: QuestionInfo;
		createIndex?: number;
		onCancel: () => void;
		onOk: () => void;
	}
	const props: Props = $props();

	let questionType: 'choice' | 'trueOrFalse' | 'simple' = $state(getQuestionType());

	let choiceQuestion: ChoiceQuestion = $state(
		props.question?.basicInfo?.question != undefined &&
			props.question.basicInfo.question.typeUrl.endsWith('.ChoiceQuestion')
			? Any.unpack(props.question.basicInfo.question, ChoiceQuestion)
			: {
					question: '',
					choiceList: []
				}
	);
	let trueOrFalseQuestion: TrueOrFalseQuestion = $state(
		props.question?.basicInfo?.question != undefined &&
			props.question.basicInfo.question.typeUrl.endsWith('.TrueOrFalseQuestion')
			? Any.unpack(props.question.basicInfo.question, TrueOrFalseQuestion)
			: {
					question: '',
					rightAnswer: false
				}
	);
	let simpleQuestion: SimpleQuestion = $state(
		props.question?.basicInfo?.question != undefined &&
			props.question.basicInfo.question.typeUrl.endsWith('.SimpleQuestion')
			? Any.unpack(props.question.basicInfo.question, SimpleQuestion)
			: {
					question: '',
					sampleAnswer: ''
				}
	);

	function getQuestionType(): 'choice' | 'trueOrFalse' | 'simple' {
		if (props.question == undefined) {
			return 'choice';
		} else {
			if (props.question.basicInfo?.question?.typeUrl.endsWith('.ChoiceQuestion')) {
				return 'choice';
			} else if (props.question.basicInfo?.question?.typeUrl.endsWith('.TrueOrFalseQuestion')) {
				return 'trueOrFalse';
			} else if (props.question.basicInfo?.question?.typeUrl.endsWith('.SimpleQuestion')) {
				return 'simple';
			}
		}
		return 'choice';
	}

	function valid(): boolean {
		if (questionType == 'choice') {
			if (choiceQuestion.question.trim() == '') {
				return false;
			}
			if (choiceQuestion.choiceList.length == 0) {
				return false;
			}
			let labelMap = new Map<string, boolean>();
			let rightCount = 0;
			for (const choice of choiceQuestion.choiceList) {
				if (choice.label.trim() == '' || choice.value.trim() == '') {
					return false;
				}
				if (labelMap.has(choice.label.trim())) {
					return false;
				}
				labelMap.set(choice.label.trim(), true);
				if (choice.rightAnswer) {
					rightCount += 1;
				}
			}
			if (rightCount == 0) {
				return false;
			}
			return true;
		} else if (questionType == 'trueOrFalse') {
			return trueOrFalseQuestion.question.trim() != "";
		} else if (questionType == 'simple') {
			return simpleQuestion.question.trim() != "";
		}
		return false;
	}

	async function createQuestion() {
		if (userStore.userSession == null || props.createIndex == undefined) {
			return;
		}
		let question: Any | null = null;
		if (questionType == 'choice') {
			question = Any.pack(choiceQuestion, ChoiceQuestion);
		} else if (questionType == 'trueOrFalse') {
			question = Any.pack(trueOrFalseQuestion, TrueOrFalseQuestion);
		} else if (questionType == 'simple') {
			question = Any.pack(simpleQuestion, SimpleQuestion);
		}
		if (question == null) {
			return;
		}

		await callApi(
			appStore.resourceExamApiClient.create({
				sessionId: userStore.userSession,
				resourceId: props.resourceId,
				questionIndex: props.createIndex,
				basicInfo: {
					question: question
				}
			}).response
		);

		props.onOk();
		appStore.addToastMessage({
			level: 'success',
			content: '创建试题成功',
			keepTime: 2000
		});
	}

	async function updateQuestion() {
		if (userStore.userSession == null || props.question == undefined) {
			return;
		}

		let question: Any | null = null;
		if (questionType == 'choice') {
			question = Any.pack(choiceQuestion, ChoiceQuestion);
		} else if (questionType == 'trueOrFalse') {
			question = Any.pack(trueOrFalseQuestion, TrueOrFalseQuestion);
		} else if (questionType == 'simple') {
			question = Any.pack(simpleQuestion, SimpleQuestion);
		}
		if (question == null) {
			return;
		}

		await callApi(
			appStore.resourceExamApiClient.updateBasic({
				sessionId: userStore.userSession,
				resourceId: props.resourceId,
				questionId: props.question.questionId,
				basicInfo: {
					question: question
				}
			}).response
		);

		props.onOk();
		appStore.addToastMessage({
			level: 'success',
			content: '修改试题成功',
			keepTime: 2000
		});
	}
</script>

<dialog class="modal modal-open">
	<div class="modal-box max-w-none w-[800px]">
		<button
			class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
			onclick={() => props.onCancel()}>✕</button
		>
		<h3 class="text-lg font-bold">
			{props.question == undefined ? '创建试题' : '修改试题'}
		</h3>
		<div class="max-h-[60vh] overflow-y-auto pr-[10px] flex-col space-y-4 pt-[20px]">
			<label class="label w-full">
				<span class="label w-[100px] text-right inline-block pr-[10px]">类型:</span>
				<select
					class="select w-full"
					bind:value={questionType}
					disabled={props.question != undefined}
				>
					<option value="choice">选择题</option>
					<option value="trueOrFalse">对错题</option>
					<option value="simple">问答题</option>
				</select>
			</label>
			{#if questionType == 'choice'}
				<EditChoiceQuestion
					question={choiceQuestion}
					onChange={(question) => (choiceQuestion = question)}
				/>
			{:else if questionType == 'trueOrFalse'}
				<EditTrueOrFalseQuestion
					question={trueOrFalseQuestion}
					onChange={(question) => (trueOrFalseQuestion = question)}
				/>
			{:else if questionType == 'simple'}
				<EditSimpleQuestion
					question={simpleQuestion}
					onChange={(question) => (simpleQuestion = question)}
				/>
			{/if}
		</div>
		<div class="modal-action mt-[60px]">
			<button class="btn" onclick={() => props.onCancel()}>取消</button>
			<button
				class="btn btn-primary"
				disabled={!valid()}
				onclick={() => {
					if (props.question == undefined) {
						createQuestion();
					} else {
						updateQuestion();
					}
				}}>{props.question == undefined ? '创建' : '修改'}</button
			>
		</div>
	</div>
	<div class="modal-backdrop">
		<button onclick={() => props.onCancel()}>close</button>
	</div>
</dialog>
